# -*- coding: utf-8 -*-

from git.repo import Repo
from com.maycur import config_loader
from com.maycur.git.base.git_operation import GitOperation
from com.maycur.git.base.gitee_operation import GiteeOperation
from com.maycur.git.base.jenkins_operation import JenkinsOperation
from com.maycur.git.base.ops_operation import OpsOperation
from com.maycur.utils import CommonUtils


def try_merge_branches():
    # 获取配置，打印待处理仓库统计数据
    git_config = config_loader.get_git_config()
    project_count = 0
    for branch_pair in git_config.branch_pairs:
        project_count = project_count + len(branch_pair.projects)
    print(f'>>> there are {project_count} projects to handle <<<')

    # 存放所有项目分支合并结果
    merge_res_list = []
    # 初始化JenkinsOperation
    jenkins_operation = JenkinsOperation(git_config)

    for branch_pair in git_config.branch_pairs:
        print(f'\nstart processing branch pair: {branch_pair.pair_name} ...')
        print('========================================================================')

        for project in branch_pair.projects:
            print(f'start processing project: [{project.name}] ...')
            repo = Repo(project.project_path)

            git_operation = GitOperation(repo, project)

            # Step 1, 检查本地仓库是否有未提交的修改，如果有，先暂存起来
            git_operation.stash_if_possible()

            # Step 2, 切换到目标分支，拉取远程仓库最新代码
            git_operation.pull_from_remote(branch_pair.up_branch)

            # Step 3, 切换到待合并的分支，拉取远程仓库最新代码
            git_operation.pull_from_remote(branch_pair.down_branch)

            """
            Step 4, 如果两个分支不一致，尝试合并，检查是否有冲突
            如果没有冲突，说明已经成功合并；如果有冲突，做统计，然后手动解决冲突
            """
            project.branches_no_diff = True
            if git_config.do_merge:
                is_diff_branches = git_operation.is_diff_branches(branch_pair.down_branch, branch_pair.up_branch)
                if is_diff_branches:
                    project.branches_no_diff = False
                    # 向下合并
                    if git_config.merge_down:
                        git_operation.pull_from_remote(branch_pair.down_branch)
                        project.merged_down = git_operation.merge_branch(project,
                                                                         branch_pair.down_branch,
                                                                         branch_pair.up_branch)
                is_diff_branches = git_operation.is_diff_branches(branch_pair.up_branch, branch_pair.down_branch)
                if is_diff_branches:
                    project.branches_no_diff = False
                    # 向上合并
                    if git_config.merge_up:
                        git_operation.pull_from_remote(branch_pair.up_branch)
                        project.merged_up = git_operation.merge_branch(project,
                                                                       branch_pair.up_branch,
                                                                       branch_pair.down_branch)

            # Step 5, 是否需要提交PullRequest
            gitee_operation = GiteeOperation(git_config.gitee_config, project)
            gitee_operation.do_pull_request_if_need(branch_pair)

            # Step 6, 是否需要提交OPS申请
            ops_operation = OpsOperation(git_config.ops_config)
            ops_operation.create_deployment_request_if_need(branch_pair, project)

            # Step 7, 是否需要部署Jenkins服务
            jenkins_operation.build_job_if_need(branch_pair, project)

            # Step 8, 统计单个项目分支合并结果
            merge_res_list.append(project)

            # Step 9, 如果合并过程中将工作区暂存了，执行stash pop操作
            git_operation.pop_stash_if_possible()

            print('------------------------------------------------------------------------')

    # Step 9, 统计所有项目分支合并结果
    statics_log_min_len = 40
    start_log = f'\n\n=====[{git_config.merge_description}]分支合并情况如下'
    print(CommonUtils.r_padding(start_log, statics_log_min_len, '='))
    no_diff_projects = []
    merged_projects = []
    conflict_projects = []
    for merge_res in merge_res_list:
        if merge_res.branches_no_diff:
            no_diff_projects.append(merge_res.name)
        elif not merge_res.has_conflict:
            if git_config.do_merge:
                # 检查分支是否成功合并
                branch_merged = False
                if git_config.merge_down and git_config.merge_up:
                    # 双向合并时，以向上合并结果为准
                    branch_merged = merge_res.merged_up
                elif git_config.merge_down:
                    branch_merged = merge_res.merged_down
                elif git_config.merge_up:
                    branch_merged = merge_res.merged_up

                if branch_merged:
                    merged_name = merge_res.name
                    if merge_res.ops_created:
                        merged_name += ' [ops]'
                    if merge_res.pr_created:
                        merged_name += ' [PullRequest]'
                    if merge_res.jenkins_deployed:
                        merged_name += ' [Jenkins]'
                    merged_projects.append(merged_name)
                else:
                    no_diff_projects.append(merge_res.name)
        else:
            conflict_projects.append(merge_res.name)
    if len(no_diff_projects) > 0:
        print(CommonUtils.r_padding(f'=====[以下服务({len(no_diff_projects)})无变更]', statics_log_min_len, '='))
        for item in no_diff_projects:
            print(item)
    if len(conflict_projects) > 0:
        print(CommonUtils.r_padding(f'=====[以下服务({len(conflict_projects)})有冲突，请手动合并]', statics_log_min_len, '='))
        for item in conflict_projects:
            print(item)
    if len(merged_projects) > 0:
        print(CommonUtils.r_padding(f'=====[以下服务({len(merged_projects)})合并成功]', statics_log_min_len, '='))
        for item in merged_projects:
            print(item)


if __name__ == '__main__':
    try_merge_branches()
